﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Xc.DataAccess.Core;

namespace Xc.DataAccess.HyperTerminalCore.Models
{
    /// <summary>
    /// 客户端通道信息
    /// </summary>
    /// <typeparam name="TType"></typeparam>
    public abstract class ClientInfo<TType> : ViewModelBase, IClientInfo<TType>
    {
        /// <summary>
        /// 客户端被关闭
        /// </summary>
        public event Action<TType> OnClose;
        /// <summary>
        /// 收到设备端的数据
        /// </summary>
        public event Action<byte[], TType,Encoding> ReceiveMessage;
        /// <summary>
        /// 设置IP地址
        /// </summary>
        /// <param name="Client"></param>
        protected virtual void SetIpAddress(Socket Client)
        {
            IpAddress = Client.RemoteEndPoint?.ToString();

        }
        /// <summary>
        /// 编码方式
        /// </summary>
        public Encoding Encoding { get; set; } = Encoding.UTF8;
        /// <summary>
        /// 发送字节码数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public abstract Task<Result> Send(byte[] buffer);
        /// <summary>
        /// 发送字符串
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public async Task<Result> Send(string content, bool isAppendLine)
        {
            if (isAppendLine)
            {
                content += Environment.NewLine;
            }
            var text = Encoding.GetBytes(content);
            return await Send(text);
        }
        int receiveCount = 0;
        /// <summary>
        /// 接收总个数
        /// </summary>
        public int ReceiveCount
        {
            get => receiveCount;
            protected set
            {
                if (receiveCount == value)
                {
                    return;
                }

                receiveCount = value;
                RaisedPropertyChanged();
            }
        }
        int sendCount;
        /// <summary>
        /// 发送总个数
        /// </summary>
        public int SendCount
        {
            get => sendCount;
            protected set
            {
                if (sendCount == value)
                {
                    return;
                }

                sendCount = value;
                RaisedPropertyChanged();
            }
        }
        /// <summary>
        /// IP地址
        /// </summary>
        public string IpAddress { get; protected set; }
        protected readonly ConcurrentQueue<byte[]> receiveBuffer = new ConcurrentQueue<byte[]>();
        protected bool UseReceive = true;
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public async Task<ResultData<T>> ReadDataByTemplate<T>(int timeout, Func<byte[], ResultData<T>> func) where T:class,new()
        {
            return await Task.Run(() =>
            {
                UseReceive = false;
                List<byte> vs = new List<byte>();
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                try
                {
                    do
                    {
                        while (receiveBuffer.TryDequeue(out var data))
                        {
                            vs.AddRange(data);
                        }
                        var d = func.Invoke(vs.ToArray());
                        if (d.IsSuccess)
                        {
                            return d;
                        }
                    } while (stopwatch.ElapsedMilliseconds < timeout);

                    return ResultData<T>.Reject("无有效信息", new T());
                }
                finally
                {
                    stopwatch.Stop();
                    UseReceive = true;

                }

            });
        }
        /// <summary>
        /// 已收到数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="type"></param>
        protected void RaisedReceiveMessage(byte[] data, TType type)
        {
            ReceiveMessage?.Invoke(data, type,this.Encoding);
        }
        protected void RaisedClose(TType type)
        {
            OnClose.Invoke(type);
        }
        /// <summary>
        /// 开始接收数据
        /// </summary>
        public void BeginRead()
        {
            UseReceive = true;
            ReceiveData();
        }
        /// <summary>
        /// 关闭通道
        /// </summary>
        public virtual void Close()
        {
            Token.Cancel();
        }
        /// <summary>
        /// 接收数据
        /// </summary>
        protected abstract void ReceiveData();
        protected CancellationTokenSource Token = new CancellationTokenSource();

        protected ClientInfo(Encoding encoding)
        {
            Encoding = encoding;
        }
    }
}
